<template>
  <div class="snippet-generator">
    <a-layout>
      <a-layout-content class="snippet-generator-content">
        <!-- 左侧输入区域 -->
        <a-card class="editor-panel" :bordered="false" title="自定义代码片段生成器">
          <template #extra>
            <a-tag color="processing">编辑区</a-tag>
          </template>
          <div class="editor-panel-header">
            <a-form layout="vertical">
              <a-form-item label="描述">
                <a-input v-model:value="description" placeholder="请输入代码片段的描述..." allow-clear :maxLength="50" show-count />
              </a-form-item>
              <a-form-item label="触发关键字">
                <a-tooltip placement="topLeft" title="输入后可通过此关键字快速触发代码片段">
                  <a-input v-model:value="tabTrigger" placeholder="请输入触发关键字..." allow-clear :maxLength="20" show-count>
                    <template #prefix>
                      <code-outlined />
                    </template>
                  </a-input>
                </a-tooltip>
              </a-form-item>
            </a-form>
          </div>
          <div class="editor-panel-body">
            <a-form-item label="代码片段">
              <a-textarea v-model:value="snippet" class="code-textarea" :auto-size="{ minRows: 20, maxRows: 20 }" placeholder="请在此输入您的代码片段..." :bordered="false" :spellcheck="false" />
            </a-form-item>
          </div>
        </a-card>

        <!-- 右侧预览区域 -->
        <a-card class="preview-panel" :bordered="false" title="预览">
          <template #extra>
            <div class="preview-actions">
              <a-radio-group v-model:value="activeEditor" button-style="solid">
                <a-radio-button v-for="editor in editors" :key="editor.id" :value="editor.id">
                  <template #icon>
                    <component :is="editor.icon" />
                  </template>
                  {{ editor.name }}
                </a-radio-button>
              </a-radio-group>
              <a-divider type="vertical" />
              <a-space>
                <a-button type="primary" @click="copySnippet" :icon="h(CopyOutlined)"> 复制代码片段 </a-button>
                <a-button @click="clearAll" :icon="h(ClearOutlined)"> 清空内容 </a-button>
              </a-space>
            </div>
          </template>
          <div class="preview-panel-body">
            <a-typography>
              <pre class="code-preview">{{ formattedSnippet }}</pre>
            </a-typography>
          </div>
        </a-card>
      </a-layout-content>
    </a-layout>
  </div>
</template>

<script setup>
import { ref, computed, h } from 'vue'
import { useClipboard } from '@vueuse/core'
import { message } from 'ant-design-vue'
import { CopyOutlined, ClearOutlined, CodeOutlined, CodepenOutlined, CodeSandboxOutlined, ThunderboltOutlined } from '@ant-design/icons-vue'

// 编辑器选项
const editors = [
  { id: 'vscode', name: 'VS Code', icon: CodepenOutlined },
  { id: 'sublimetext', name: 'Sublime', icon: CodeSandboxOutlined },
  { id: 'atom', name: 'Atom', icon: ThunderboltOutlined }
]

// 响应式状态
const activeEditor = ref('vscode')
const description = ref('')
const tabTrigger = ref('')
const snippet = ref('')

// 剪贴板功能
const { copy } = useClipboard()

// 格式化代码片段
const formattedSnippet = computed(() => {
  if (!snippet.value) return ''

  const lines = snippet.value
    .split('\n')
    .map((line) => JSON.stringify(line))
    .join(',\n    ')

  switch (activeEditor.value) {
    case 'vscode':
      return `"${description.value}": {
  "prefix": "${tabTrigger.value}",
  "body": [
    ${lines}
  ],
  "description": "${description.value}"
}`
    case 'sublimetext':
      return `<snippet>
  <content><![CDATA[${snippet.value}]]></content>
  <tabTrigger>${tabTrigger.value}</tabTrigger>
  <description>${description.value}</description>
</snippet>`
    case 'atom':
      return `'.source':
  '${description.value}':
    'prefix': '${tabTrigger.value}'
    'body': """
${snippet.value}
    """`
    default:
      return ''
  }
})

// 复制代码片段
const copySnippet = async () => {
  if (!snippet.value) {
    message.warning('请先输入代码片段')
    return
  }
  try {
    await copy(formattedSnippet.value)
    message.success('代码片段已复制到剪贴板！')
  } catch (err) {
    message.error('复制失败，请重试')
  }
}

// 清空所有内容
const clearAll = () => {
  description.value = ''
  tabTrigger.value = ''
  snippet.value = ''
  message.success('已清空所有内容')
}
</script>

<style scoped>
.snippet-generator {
  height: calc(100vh - 64px);
  background: #f0f2f5;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.preview-panel-body {
  height: 100%;
  width: 100%;
}
.ant-typography {
  height: 100%;
  width: 100%;
}

.code-preview {
  border-radius: 5px;
  line-height: 1.6;
  transition: all 0.3s ease;
  font-size: 14px;
  width: 100%;
  height: 100%;
  display: block;
  overflow-y: auto;
  white-space: pre-wrap;
  word-wrap: break-word;
  word-break: break-all;
  background: #f8f9fa;
  padding: 16px;
  margin: 0;
  border: 1px solid #e8e8e8;
  font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
}

.snippet-generator-content {
  padding: 24px;
  display: flex;
  gap: 24px;
  flex: 1;
  overflow: auto;
  height: auto;
}

.editor-panel,
.preview-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 600px;
  transition: all 0.3s ease;
  overflow: hidden;
}

.editor-panel:hover,
.preview-panel:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.code-textarea {
  width: 100%;
  display: block;
  resize: none;
  padding: 16px;
  border-radius: 8px;
  line-height: 1.6;
  transition: all 0.3s ease;
  border: 1px solid #e0e0e0;
}

.code-textarea:focus {
  background: #fff;
  box-shadow: inset 0 0 0 2px #1890ff;
}

.preview-actions {
  display: flex;
  align-items: center;
  gap: 16px;
}

:deep(.ant-card-head) {
  border-bottom: 1px solid #f0f0f0;
  padding: 0 16px;
}

:deep(.ant-card) {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

:deep(.ant-card-body) {
  flex: 1;
  padding: 16px;
  overflow: auto;
  padding-right: 12px;
}

:deep(.ant-form-item) {
  margin-bottom: 16px;
}

:deep(.ant-radio-button-wrapper) {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

:deep(.ant-alert) {
  margin-bottom: 16px;
  border-radius: 8px;
}

:deep(.ant-input-affix-wrapper) {
  border-radius: 4px;
}

:deep(.ant-input-affix-wrapper:hover) {
  border-color: #1890ff;
}

:deep(.ant-divider) {
  margin: 0 8px;
}

:deep(.ant-card-body::-webkit-scrollbar) {
  width: 6px;
}

:deep(.ant-card-body::-webkit-scrollbar-thumb) {
  background-color: rgba(0, 0, 0, 0.2);
  border-radius: 3px;
}

:deep(.ant-card-body::-webkit-scrollbar-track) {
  background-color: transparent;
}

@media (max-width: 768px) {
  .snippet-generator {
    height: 100dvh;
  }

  .snippet-generator-content {
    flex-direction: column;
  }

  .editor-panel,
  .preview-panel {
    min-height: 400px;
  }

  .preview-actions {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }

  :deep(.ant-radio-group) {
    display: flex;
    margin-bottom: 8px;
  }

  :deep(.ant-radio-button-wrapper) {
    flex: 1;
    text-align: center;
    justify-content: center;
  }
}
</style>
